home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
programr
/
tkern10.zip
/
SRC\STDIO.C
< prev
next >
Wrap
Text File
|
1994-07-09
|
8KB
|
535 lines
/*
* This file forms part of "TKERN" - "Troy's Kernel for Windows".
*
* Copyright (C) 1994 Troy Rollo <troy@cbme.unsw.EDU.AU>
*
* This file is explicitly placed in the public domain. You may use it
* it for any purpose you see fit, including, but not limited to,
* incorperating it into a private, commercial, public domain,
* shareware, freeware or free software work.
*/
#include <windows.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <stdarg.h>
#include <stdlib.h>
#include <memory.h>
int
__formatter( int (*func)(void *a, char b),
void *func_arg,
char const *format,
va_list arg);
#define MAXFILES 20
#define BUFSIZ 2048
FILE _iob[MAXFILES];
static int getmodes(char const *mode,
int *flags)
{
int plus = 0;
int reading = 0;
int writing = 0;
int binary = 0;
int appending = 0;
int modes;
*flags = 0;
while (*mode)
{
switch(*mode++)
{
case 'w':
writing = 1;
break;
case 'r':
reading = 1;
break;
case 'a':
appending = 1;
break;
case 'b':
binary = 1;
break;
case 't':
binary = 0;
break;
case '+':
plus = 1;
break;
}
}
if (writing)
{
if (plus || reading)
{
*flags = __FL_READ | __FL_WRITE;
modes = O_RDWR | O_CREAT | O_TRUNC;
}
else
{
*flags = __FL_WRITE;
modes = O_WRONLY | O_CREAT | O_TRUNC;
}
}
else if (appending)
{
if (plus || reading)
{
*flags = __FL_READ | __FL_WRITE;
modes = O_RDWR | O_CREAT;
}
else
{
*flags = __FL_WRITE;
modes = O_WRONLY | O_CREAT;
}
}
else if (reading)
{
if (plus)
{
*flags = __FL_READ | __FL_WRITE;
modes = O_RDWR;
}
else
{
*flags = __FL_READ;
modes = O_RDONLY;
}
}
if (binary)
modes |= O_BINARY;
else
modes |= O_TEXT;
return modes;
}
static void _flsbuf(FILE *fp)
{
if (fp->flags & __FL_MODIFIED)
{
lseek(fp->fd, -fp->readsize, 1);
write(fp->fd, fp->buffer, fp->bufsize);
fp->flags &= ~__FL_MODIFIED;
}
}
static int _filbuf(FILE *fp)
{
_flsbuf(fp);
if (fp->flags & __FL_READ)
fp->bufsize = read(fp->fd, fp->buffer, BUFSIZ);
else
fp->bufsize = 0;
if (!fp->bufsize)
{
fp->flags |= __FL_EOF;
}
else if (fp->bufsize == -1)
{
fp->bufsize= 0;
fp->flags |= __FL_ERROR;
fp->readsize = 0;
}
else
{
fp->flags &= ~(__FL_ERROR | __FL_EOF);
fp->readsize = fp->bufsize;
}
fp->bufidx = 0;
return fp->bufsize;
}
FILE *fopen(char const *name, char const *mode)
{
int fd;
FILE *fp;
int modes;
int flags;
modes = getmodes(mode, &flags);
fd = open(name, modes, 0666);
if (fd == -1)
return 0;
return fdopen(fd, mode);
}
FILE *fdopen(int fd, char const *mode)
{
int modes;
FILE *fp;
int flags;
modes = getmodes(mode, &flags);
fp = &_iob[fd];
fp->fd = fd;
fp->modes = modes;
fp->flags = flags;
if (fp->buffer)
{
free(fp->buffer);
fp->buffer = 0;
fp->bufsize = 0;
fp->bufidx = 0;
}
if (!isatty(fd))
{
fp->buffer = (char *) malloc(BUFSIZ);
fp->bufsize = BUFSIZ;
fp->bufidx = BUFSIZ;
_filbuf(fp);
}
return fp;
}
int fclose(FILE *fp)
{
_flsbuf(fp);
close(fp->fd);
if (fp->buffer)
{
free(fp->buffer);
fp->bufsize = 0;
fp->bufidx = 0;
fp->buffer = 0;
}
fp->fd = -1;
fp->flags = 0;
fp->modes = 0;
return 0;
}
void _init_all_files(void)
{
int i;
for (i = 0; i < MAXFILES; i++)
_iob[i].fd = -1;
}
void _close_all_files(void)
{
int fd;
for (fd = 0; fd < MAXFILES; fd++)
{
if (_iob[fd].fd != -1)
{
fclose(&_iob[fd]);
}
}
}
FILE *freopen(char const *file, char const *mode, FILE *fp)
{
FILE *fpNew;
if (fp->fd != -1)
fclose(fp);
fpNew = fopen(file, mode);
if (!fpNew)
return 0;
if (fp == fpNew)
return fp;
dup2(fpNew->fd, fp - _iob);
fclose(fpNew);
return fdopen(fp - _iob, mode);
}
int ungetc(char c, FILE *fp)
{
if (fp->flags & __FL_UNGET)
return EOF;
fp->flags |= __FL_UNGET;
fp->ungetchar = c;
return 0;
}
int getc(FILE *fp)
{
char c;
if (fp->flags & __FL_UNGET)
{
fp->flags &= ~__FL_UNGET;
return (unsigned) (unsigned char) fp->ungetchar;
}
else if (fp->buffer)
{
if (fp->bufidx < fp->bufsize)
return (unsigned) (unsigned char) (fp->buffer[fp->bufidx++]);
else if (_filbuf(fp))
return (unsigned) (unsigned char) fp->buffer[fp->bufidx++];
else
return EOF;
}
else if (read(fp->fd, &c, 1) == 1)
return (unsigned) (unsigned char) c;
else
return EOF;
}
int putc(char c, FILE *fp)
{
if (fp->buffer)
{
if (fp->bufidx < BUFSIZ)
{
fp->buffer[fp->bufidx++] = c;
if (fp->bufidx > fp->bufsize)
fp->bufsize = fp->bufidx;
}
else
{
_filbuf(fp);
fp->buffer[fp->bufidx++] = c;
}
fp->flags |= __FL_MODIFIED;
return c;
}
else
{
if (write(fp->fd, &c, 1) == 1)
return c;
else
return EOF;
}
}
int fscanf(FILE *fp, char const *format, ...)
{
va_list args;
int retval;
va_start(args, format);
retval = vfscanf(fp, format, args);
va_end(args);
return retval;
}
int scanf(char const *format, ...)
{
va_list args;
int retval;
va_start(args, format);
retval = vfscanf(stdin, format, args);
va_end(args);
return retval;
}
int fp_fmtout(void *pv, char c)
{
FILE *fp = (FILE *) pv;
putc(c, fp);
return 1;
}
int vfprintf(FILE *fp, char const *format, va_list arg)
{
return __formatter(fp_fmtout, fp, format, arg);
}
int fprintf(FILE *fp, char const *format, ...)
{
va_list args;
int retval;
va_start(args, format);
retval = vfprintf(fp, format, args);
va_end(args);
return retval;
}
int printf(char const *format, ...)
{
va_list args;
int retval;
va_start(args, format);
retval = vfprintf(stdout, format, args);
va_end(args);
return retval;
}
int puts(char const *pch)
{
while (*pch)
if (putchar(*pch) == EOF)
return EOF;
else
pch++;
if (putchar('\n') == EOF)
return EOF;
return 0;
}
char *gets(char *pch)
{
char c;
char *pchOut = pch;
while (1)
{
c = getchar();
if (c == EOF)
return 0;
if (c == '\n')
{
*pchOut = '\0';
return pch;
}
*pchOut++ = c;
}
}
int fputs(char const *pch, FILE *fp)
{
while (*pch)
if (putc(*pch, fp) == EOF)
return EOF;
else
pch++;
return 0;
}
char *fgets(char *pch, int nMax, FILE *fp)
{
char c;
char *pchOut = pch;
while (--nMax)
{
c = getc(fp);
if (c == EOF)
return 0;
*pchOut++ = c;
if (c == '\n')
break;
}
*pchOut = '\0';
return pch;
}
int
fread( char *pchBuffer,
int nSize,
int nCount,
FILE *fp)
{
int nRead = 0;
int nReadSize = nSize * nCount;
int nNow;
if (nReadSize == 0)
return 0;
if (fp->flags & __FL_UNGET)
{
fp->flags &= ~__FL_UNGET;
*pchBuffer++ = fp->ungetchar;
nRead++;
}
if (fp->buffer)
{
while (nRead < nReadSize)
{
if (nReadSize - nRead < fp->bufsize - fp->bufidx)
nNow = nReadSize - nRead;
else
nNow = fp->bufsize - fp->bufidx;
if (nNow)
{
memcpy(pchBuffer, fp->buffer + fp->bufidx, nNow);
fp->bufidx += nNow;
pchBuffer += nNow;
nRead += nNow;
}
else if (!_filbuf(fp))
{
return nRead / nSize;
}
}
return nCount;
}
else
{
nRead = read(fp->fd, pchBuffer, nReadSize);
if (nRead <= -1)
return EOF;
return nRead / nSize;
}
}
int
fwrite( char const *pchBuffer,
int nSize,
int nCount,
FILE *fp)
{
int nWritten = 0;
int nToWrite = nSize * nCount;
int nNow;
if (fp->buffer)
{
while (nWritten < nToWrite)
{
if (BUFSIZ - fp->bufidx < nToWrite - nWritten)
nNow = BUFSIZ - fp->bufidx;
else
nNow = nToWrite - nWritten;
if (nNow)
{
memcpy(fp->buffer + fp->bufidx, pchBuffer, nNow);
pchBuffer += nNow;
fp->bufidx += nNow;
nWritten += nNow;
if (fp->bufidx > fp->bufsize)
fp->bufsize = fp->bufidx;
fp->flags |= __FL_MODIFIED;
}
else
{
_filbuf(fp);
}
}
return nWritten / nSize;
}
else
{
nWritten = write(fp->fd, (void *) pchBuffer, nToWrite);
if (nWritten < 0)
return EOF;
return nWritten / nSize;
}
}
int ferror(FILE *fp)
{
return (fp->flags & __FL_ERROR) ? 1 : 0;
}